import com.github.kotlintelegrambot.Bot
import com.github.kotlintelegrambot.bot
import com.github.kotlintelegrambot.dispatch
import com.github.kotlintelegrambot.dispatcher.message
import com.github.kotlintelegrambot.entities.ChatAction
import com.github.kotlintelegrambot.entities.ChatId
import com.github.kotlintelegrambot.entities.Message
import dto.AppConfig
import dto.MessageFromTg
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.slf4j.Logger

class BotModelImpl(
    private val appConfig: AppConfig,
    private val assistant: Assistant,
    private val redis: DatabaseRedis,
    private val logInfo: Logger,
    private val logError: Logger,
) : BotModel {

    private val bot = bot {
        token = appConfig.botToken
        dispatch {
            message {
                runBlocking {
                    if (message.text == "/start") {
                        onStart(message)
                    } else if (message.text?.contains("/setStartMessage") == true) {
                        setStartMessage(message.chat.id, message.text ?: "HI, {user}")
                    } else {
                        if (message.chat.id != appConfig.excludedChatId.toLong()) {
                            default(message)
                        }
                    }
                }
            }
        }
    }

    override fun sendTextMessage(id: Long, text: String): Boolean {
        logInfo.info(
            "Sending message\n" +
                    "To: $id" +
                    "Text: $text"
        )
        val isOk = bot.sendMessage(ChatId.fromId(id), text).isSuccess
        if (!isOk) {
            logError.error(
                "Fail sending message\n" +
                        "To: $id" +
                        "Text: $text"
            )
        }
        return isOk
    }

    override suspend fun onStart(message: Message) {
        withContext(Dispatchers.Default) {
            val username = message.from?.firstName ?: message.from?.username ?: "искатель бетона"
            val text = redis.getStartMessage()?.replace("{user}", username) ?: "HI, $username"
            sendTextMessage(message.chat.id, text)
            sendTextMessage(appConfig.groupChatId.toLong(),"Пользователь $username\nhttps://t.me/${message.from?.username}\n" +
                    "Подключился к боту")
        }
    }

    override suspend fun setStartMessage(id: Long, text: String) {
        if (!checkAdmin(id)) return
        val new = text.replace("/setStartMessage", "")
        if (new.isEmpty()) return
        redis.setStartMessage(new)
        sendTextMessage(id, "Новое приветственное собщение успешно установленно")
    }

    override suspend fun addAdmin(id: Long, newId: Long) {

        if (!checkAdmin(id)) return
        redis.addAdmin(newId.toString())
    }

    override suspend fun deleteAdmin(id: Long, deleteId: Long) {
        if (!checkAdmin(id)) return
        redis.deleteAdmin(deleteId.toString())
    }

    override suspend fun checkAdmin(id: Long): Boolean {
        return id.toString() in redis.getAdmins()
    }

    override suspend fun default(message: Message) {
        bot.sendChatAction(ChatId.fromId(message.chat.id), ChatAction.TYPING)
        assistant.getMessage(MessageFromTg(message.chat.id.toString(), message.text ?: "hi"))
    }

    override suspend fun sendToGroupChat(text: String) {
        bot.sendMessage(ChatId.fromId(appConfig.groupChatId.toLong()), text)
    }



    override fun getBot(): Bot = bot
}